#include "plot.h"
#include <QDateTime>
#include "qpainter.h"
#include <QDebug>
#include <QPixmap>
#include <QPixmapCache>
#include <QSpacerItem>
#include <QGridLayout>
CoorAxis::CoorAxis(QWidget *parent, Ticker *ticker) : QWidget(parent)
{
    m_LastLength=0;
    m_margin=2;
    m_Ticker=ticker;
}
CoorAxis::~CoorAxis()
{
//    if(m_Ticker){
//        delete m_Ticker;
//        m_Ticker=NULL;
//    }
}

void CoorAxis::slots_sendCoorWheel(QWheelEvent *event)
{
    this->wheelEvent(event);
}

void CoorAxis::slots_sendCoorMouse(QMouseEvent *event, QPoint point, bool IsFirst)
{
    if(IsFirst){
        m_FirstPoint=point;
        m_Ticker->InitScale();
    }else{
        this->mouseMove(event);
    }
}

void CoorAxis::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
//  painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    switch (m_Ticker->getAxisType())
    {
    case _TICKERTYPE::XAxis:
        drawTickerX(&painter);
        break;
    case _TICKERTYPE::YAxis_L:
        drawTickerY_L(&painter);
        break;
    case _TICKERTYPE::YAxis_R:
        drawTickerY_R(&painter);
        break;
    default:
        break;
    }
}

void CoorAxis::drawTickerX(QPainter *painter)
{
    painter->save();
    QPen Pen(QColor(100,100,100));
    Pen.setWidthF(0.5);
    painter->setPen(Pen);
    QString TmpStrValue;

    double Score=(m_Ticker->getRangeEnd()-m_Ticker->getRangeBeg())/m_Ticker->getMainLineCount();
    double TickerValue=0.0;
    double Width=width();
    double Height=height();
    double TextHeight=fontMetrics().height();
    double TextWidth=0;
    double MainSpace;
    int MainLineCount=m_Ticker->getMainLineCount();
    double MainOffset=0.0;
    int TmpSize=0;

    MainSpace=Width/MainLineCount;
    //根据主刻度数目进行绘制
    for(int index=0;index<=MainLineCount;index++)
    {
        TickerValue=m_Ticker->getRangeBeg()+Score*index;
        switch (m_Ticker->m_TextType)
        {
        case _TEXT_TYPE::_TimeS:
            TmpStrValue=QDateTime::fromMSecsSinceEpoch(TickerValue).toString("yyyy-MM-dd hh:mm:ss");
            break;
        case _TEXT_TYPE::_TimeMs:
            TmpStrValue=QDateTime::fromMSecsSinceEpoch(TickerValue).toString("MM-dd hh:mm:ss:zzz");
            break;
        case _TEXT_TYPE::CountVal:
            TmpStrValue=QString::number(TickerValue,'f',2);
            break;
        default:
            break;
        }
        TextWidth=fontMetrics().width(TmpStrValue);
        MainOffset=MainSpace*index;
        //绘制文本
        if(index==0){
            painter->drawText(MainOffset+m_margin,Height-TextHeight,TmpStrValue);
        }else if(index==MainLineCount){
            painter->drawText(MainOffset-TextWidth,Height-TextHeight,TmpStrValue);
        }else{
            painter->drawText(MainOffset-(TextWidth/2)-m_margin,Height-TextHeight,TmpStrValue);
        }
    }
    //设置最小高度
    TmpSize=TextHeight*2+m_margin-1;
    QSize SizeTmp=size();
    if(TmpSize!=SizeTmp.height())
    {
        SizeTmp.setHeight(TmpSize);
        this->setMinimumHeight(SizeTmp.height());
    }
    painter->restore();
}
void CoorAxis::drawTickerY_L(QPainter *painter)
{
    painter->save();
    QPen Pen(QColor(100,100,100));
    Pen.setWidthF(0.5);
    painter->setPen(Pen);

    QString TmpStrValue;
    double Score=(m_Ticker->getRangeEnd()-m_Ticker->getRangeBeg())/m_Ticker->getMainLineCount();
    double Height=height();
    double TextHeight=fontMetrics().height();
    double TextWidth=0;
    double MainSpace;
    int MainLineCount=m_Ticker->getMainLineCount();
    double MainOffset=0.0;
    int TmpSize=0;

    MainSpace=Height/MainLineCount;

    //根据主刻度绘制
    for(int index=0;index<=MainLineCount;index++)
    {
        TmpStrValue=QString::number(m_Ticker->getRangeEnd()-Score*index,'f',2);
        //计算最长的文本宽度
        if(TextWidth<=fontMetrics().width(TmpStrValue)){
            TextWidth=fontMetrics().width(TmpStrValue);
        }

        MainOffset=MainSpace*index;
        //绘制文本
        if(index==0)
        {
            painter->drawText(m_margin,TextHeight,TmpStrValue);
        }else if(index==MainLineCount){
            painter->drawText(m_margin,MainOffset-TextHeight/4,TmpStrValue);
        }else{
            painter->drawText(m_margin,MainOffset+TextHeight/2,TmpStrValue);
        }
    }
    //设置最小宽度
    TmpSize=TextWidth+m_margin*2-1;
    QSize SizeTmp=size();
    if(TmpSize!=SizeTmp.width())
    {
        SizeTmp.setWidth(TmpSize);
        this->setMinimumWidth(SizeTmp.width());
    }
    painter->restore();
}

void CoorAxis::drawTickerY_R(QPainter *painter)
{
    painter->save();
    QPen Pen(QColor(100,100,100));
    Pen.setWidthF(0.5);
    painter->setPen(Pen);

    QString TmpStrValue;
    double Score=(m_Ticker->getRangeEnd()-m_Ticker->getRangeBeg())/m_Ticker->getMainLineCount();
    double Height=height();
    double TextHeight=fontMetrics().height();
    double TextWidth=0;
    double MainSpace;
    int MainLineCount=m_Ticker->getMainLineCount();
    int SubLineCount=m_Ticker->getSubLineCount();
    double MainOffset=0.0;
    int TmpSize=0;

    MainSpace=Height/MainLineCount;
    //根据主刻度绘制文本
    double TextStartX;
    for(int index=0;index<=MainLineCount;index++)
    {
        TmpStrValue=QString::number(m_Ticker->getRangeEnd()-Score*index,'f',2);
        //计算最长的文本宽度
        if(TextWidth<=fontMetrics().width(TmpStrValue)){
            TextWidth=fontMetrics().width(TmpStrValue);
        }
        MainOffset=MainSpace*index;
        //绘制文本
        if(index==0)
        {
            TextStartX=m_Ticker->getMainLineLength()+m_margin;
            painter->drawText(TextStartX,TextHeight,TmpStrValue);
        }else if(index==MainLineCount){
            painter->drawText(TextStartX,MainOffset-TextHeight/4,TmpStrValue);
        }else{
            painter->drawText(TextStartX,MainOffset+TextHeight/2,TmpStrValue);
        }
    }
    //设置最小宽度
    TmpSize=TextWidth+m_margin*2+m_Ticker->getMainLineLength()-1;
    QSize SizeTmp=size();
    if(TmpSize!=SizeTmp.width())
    {
        SizeTmp.setWidth(TmpSize);
        this->setMinimumWidth(SizeTmp.width());
    }
    painter->restore();
}

void CoorAxis::wheelEvent(QWheelEvent *event)
{
    QPoint Point=event->angleDelta();
    if(Point.y()==0){
        QWidget::wheelEvent(event);
        return ;
    }
    static int lastValY=0;
    if(qAbs(Point.y()-lastValY)>240){//过滤一些奇怪的东西
        lastValY=Point.y();
        return ;
    }
    lastValY=Point.y();
    double interval=Point.y()/30;
    double offsetval=qAbs((m_Ticker->getRangeEnd()-m_Ticker->getRangeBeg())*0.03);
    offsetval=offsetval*interval;

    m_Ticker->setRange(m_Ticker->getRangeBeg()+offsetval,m_Ticker->getRangeEnd()-offsetval);
    emit sig_UpdateUI();
}

void CoorAxis::mousePressEvent(QMouseEvent *event)
{
    IsPress=true;
    m_FirstPoint=event->pos();
    m_Ticker->InitScale();
    QWidget::mousePressEvent(event);
}

void CoorAxis::mouseReleaseEvent(QMouseEvent *event)
{
    IsPress=false;
    QWidget::mousePressEvent(event);
}

void CoorAxis::mouseMoveEvent(QMouseEvent *event)
{
    if(IsPress)
    {
        this->mouseMove(event);
    }
    QWidget::mouseMoveEvent(event);
}
void CoorAxis::mouseMove(QMouseEvent *event)
{
    double diffval=0;
    double offsetval=0;
    double diffRange=qAbs(m_Ticker->getRangeEnd()-m_Ticker->getRangeBeg());

    if(m_Ticker->getAxisType()==_TICKERTYPE::XAxis){
        diffval=event->pos().x()-m_FirstPoint.x();
        offsetval=(diffRange/width())*diffval*-1;
    }else{
        diffval=event->pos().y()-m_FirstPoint.y();
        offsetval=(diffRange/height())*diffval;
    }

    m_Ticker->setRange(m_Ticker->getScale()._begVal+offsetval,m_Ticker->getScale()._endVal+offsetval);
    emit sig_UpdateUI();
}

//====================================================================================
Plot::Plot(QWidget *parent): QWidget(parent)
{
    setAttribute(Qt::WA_AcceptTouchEvents, true);
    m_IsDrawPath=true;

    m_TickerX=new Ticker();
    m_TickerR=new Ticker();
    m_TickerR->setAxisType(_TICKERTYPE::YAxis_R);
    m_TickerL=new Ticker();
    m_TickerL->setAxisType(_TICKERTYPE::YAxis_L);

    setBackgroundColor(QColor(0,0,0));
    setTrackVisibel(true);
    this->ValueInit();
}

Plot::~Plot()
{
    if(m_TickerX){
        delete m_TickerX;
        m_TickerX=NULL;
    }
    if(m_TickerL){
        delete m_TickerL;
        m_TickerL=NULL;
    }
    if(m_TickerR){
        delete m_TickerR;
        m_TickerR=NULL;
    }
}

void Plot::ValueInit()
{

}

Ticker *Plot::tickerX()
{
    if(!m_TickerX){
        m_TickerX=new Ticker();
    }
    return m_TickerX;
}

Ticker *Plot::tickerL()
{
    if(!m_TickerL){
        m_TickerL=new Ticker();
    }
    return m_TickerL;
}

Ticker *Plot::tickerR()
{
    if(!m_TickerR){
        m_TickerR=new Ticker();
    }
    return m_TickerR;
}

void Plot::addGraph()
{
    _XYList Tmp;
    int Count=m_XyGraph.count();

    QColor color(255,255,255);
    switch (Count%8)
    {
    case 0:
        color=QColor(255,0,0);
        break;
    case 1:
        color=QColor(249,143,0);
        break;
    case 2:
        color=QColor(0,122,255);
        break;
    case 3:
        color=QColor(90,133,131);
        break;
    case 4:
        color=QColor(0,171,0);
        break;
    case 5:
        color=QColor(120,21,162);
        break;
    case 6:
        color=QColor(255,0,128);
        break;
    case 7:
        color=QColor(0,181,205);
        break;
    default:
        break;
    }
    Tmp.setColor(color);
    m_XyGraph.append(Tmp);
}

_XYList *Plot::Graph(int index)
{
    if(index>getGraphCount()){
        return &m_XyGraph[0];
    }
    return &m_XyGraph[index];
}

void Plot::coordToPixel(_COORDINATEVALUE *Value, _TICKERTYPE Type)
{
    double XScale=1.0;
    double YScale=1.0;
    double RangeBeg=m_TickerX->getRangeBeg();
    double RangeEnd=m_TickerX->getRangeEnd();

    switch (Type) {
    case _TICKERTYPE::YAxis_L:
        XScale=width()/(RangeEnd-RangeBeg);
        YScale=height()/(m_TickerL->getRangeEnd()-m_TickerL->getRangeBeg());
        Value->Key=(Value->Key-RangeBeg)*XScale;
        Value->Value=(Value->Value-m_TickerL->getRangeBeg())*YScale;
        break;
    case _TICKERTYPE::YAxis_R:
        XScale=width()/(RangeEnd-RangeBeg);
        YScale=height()/(m_TickerR->getRangeEnd()-m_TickerR->getRangeBeg());
        Value->Key=(Value->Key-RangeBeg)*XScale;
        Value->Value=(Value->Value-m_TickerR->getRangeBeg())*YScale;
        break;
    default:
        break;
    }
}
void Plot::coordToPixel(double &key,double &value,_TICKERTYPE Type)
{
    double XScale=1.0;
    double YScale=1.0;
    double RangeBeg=m_TickerX->getRangeBeg();
    double RangeEnd=m_TickerX->getRangeEnd();
    switch (Type)
    {
    case _TICKERTYPE::YAxis_L:
        XScale=width()/(RangeEnd-RangeBeg);
        YScale=height()/(m_TickerL->getRangeEnd()-m_TickerL->getRangeBeg());
        key=(key-RangeBeg)*XScale;
        value=(value-m_TickerL->getRangeBeg())*YScale;
        break;
    case _TICKERTYPE::YAxis_R:
        XScale=width()/(RangeEnd-RangeBeg);
        YScale=height()/(m_TickerR->getRangeEnd()-m_TickerR->getRangeBeg());
        key=(key-RangeBeg)*XScale;
        value=(value-m_TickerR->getRangeBeg())*YScale;
        break;
    default:
        break;
    }
}


void Plot::PixelToCoorKey(double &key, _TICKERTYPE Type)
{
    double RangeBeg=0;
    double RangeEnd=0;
    RangeBeg=m_TickerX->getRangeBeg();
    RangeEnd=m_TickerX->getRangeEnd();
    double XScale=width()/(RangeEnd-RangeBeg);
    key=(key/XScale)+RangeBeg;
}

void Plot::PixelToCoorValue(double &value, _TICKERTYPE Type)
{
    double RangeBeg=0;
    double RangeEnd=0;
    switch (Type)
    {
    case _TICKERTYPE::YAxis_L:
        RangeBeg=m_TickerL->getRangeBeg();
        RangeEnd=m_TickerL->getRangeEnd();
        break;
    case _TICKERTYPE::YAxis_R:
        RangeBeg=m_TickerR->getRangeBeg();
        RangeEnd=m_TickerR->getRangeEnd();
        break;
    default:
        break;
    }
    double YScale=height()/(RangeEnd-RangeBeg);
    value=(value/YScale)+RangeBeg;
}

void Plot::PixelToCoord(QPointF &pointf, _TICKERTYPE Type)
{
    double Scale=width()/(m_TickerX->getRangeEnd()-m_TickerX->getRangeBeg());
    double key=(pointf.x()/Scale)+m_TickerX->getRangeBeg();
    pointf.setX(key);

    double RangeBeg=0;
    double RangeEnd=0;
    switch (Type)
    {
    case _TICKERTYPE::YAxis_L:
        RangeBeg=m_TickerL->getRangeBeg();
        RangeEnd=m_TickerL->getRangeEnd();
        break;
    case _TICKERTYPE::YAxis_R:
        RangeBeg=m_TickerR->getRangeBeg();
        RangeEnd=m_TickerR->getRangeEnd();
        break;
    default:
        break;
    }
    Scale=height()/(RangeEnd-RangeBeg);
    double value=(pointf.y()/Scale)+RangeBeg;
    pointf.setY(value);
}
void Plot::getOptimizedLineData(QVector<QPointF> *lineData, int index)
{
    if(Graph(index)->Count()<=0){return ; }
    int begindex=Graph(index)->getBegindex(m_TickerX->getRangeBeg());
    int endindex=Graph(index)->getEndindex(m_TickerX->getRangeEnd());
    if(begindex>Graph(index)->getRemoveCount()){begindex-=1;}//多减一个点，用直线填补坐标内没有数据的部分，所以添加下没在坐标内的上一个点
    if(endindex<(Graph(index)->CountAll()-1)){endindex+=1;}//多加一个点，用直线填补坐标内没有数据的部分，所以添加下没在坐标内的下一个点
    QVector<_COORDINATEVALUE>::const_iterator begIte=m_XyGraph[index].data()->begin()+begindex;
    QVector<_COORDINATEVALUE>::const_iterator endIte=m_XyGraph[index].data()->begin()+endindex;

   // qDebug()<<"index"<<begindex<<endindex<<(qint64)m_XyGraph[index].getPoint(endindex).Key<<(qint64)endIte->Key<<Graph(index)->getRemoveCount();
    int dataCount = endIte-begIte;
    if(endIte!=begIte)
    {
        dataCount+=1;
    }
    if(dataCount<=0){
        return ;
    }

    double minValue = begIte->Value;
    double maxValue = begIte->Value;
    double FirstKey = begIte->Key;
    double lastIntervalEndKey = begIte->Key;
    int intervalDataCount = 0;
    _COORDINATEVALUE BegCoor=*begIte;
    _COORDINATEVALUE EndCoor=*endIte;
    this->coordToPixel(&BegCoor,Graph(index)->getAixsType());
    this->coordToPixel(&EndCoor,Graph(index)->getAixsType());
    double widthdiff=EndCoor.Key-BegCoor.Key;//有效像素宽度差,即可以绘制的有效点数
    double keyEpsilon=(endIte->Key-begIte->Key)/(widthdiff);//点数间的坐标间隔，多长坐标范围取一个数据点

    //qDebug()<<keyEpsilon<<widthdiff<<(endIte->Key-begIte->Key);
    QVector<_COORDINATEVALUE>::const_iterator FirstPoint=begIte;
    if(dataCount >= widthdiff)
    {
        while (begIte != endIte)
        {
            if (begIte->Key <(FirstKey+keyEpsilon)) //当前位置点的X值小于第一点数据加第一点到间隔最好一点的数据,求最大最小值
            {
                if (begIte->Value < minValue)
                {
                    minValue = begIte->Value;
                }else if (begIte->Value > maxValue)
                {
                    maxValue = begIte->Value;
                }
                ++intervalDataCount;
            }else // new pixel interval started
            {
                //上一次间隔的值小于当前间隔第一个值减去间隔值，出现的地方：两点间隔过大的开始点用实际的第一个点
                if (lastIntervalEndKey < (FirstKey-keyEpsilon)) // last point is further away, so first point of this cluster must be at a real data point
                {
                    lineData->append(QPointF(FirstKey+keyEpsilon*0.2, FirstPoint->Value));
                   // qDebug()<<"lastIntervalEndKey Start"<<keyEpsilon;
                }
                lineData->append(QPointF(FirstKey+keyEpsilon*0.25, minValue));
                lineData->append(QPointF(FirstKey+keyEpsilon*0.75, maxValue));
                //qDebug()<<FirstKey<<keyEpsilon<<FirstKey+keyEpsilon*0.25<<FirstKey+keyEpsilon*0.75;
                //当前点大于X大于当前间隔第一个点加两个间隔值，则把最后一个点(begIte-1)->Value)放到间隔80%的位置，
                //begIte->Key是下一次间隔的起始点，出现的地方：两点间隔过大的结束点用实际的最后一个点
                if (begIte->Key >(FirstKey+keyEpsilon*2)) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point
                {
                    lineData->append(QPointF(FirstKey+keyEpsilon*0.8, (begIte-1)->Value));
                }
                lastIntervalEndKey = (begIte-1)->Key;
                minValue = begIte->Value;
                maxValue = begIte->Value;
                FirstPoint = begIte;
                FirstKey =begIte->Key;
                intervalDataCount = 0;
            }
            ++begIte;
        }
        if (intervalDataCount >= 1) // last pixel had multiple data points, consolidate them to a cluster
        {
            if (lastIntervalEndKey < FirstKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point
            {
                lineData->append(QPointF(FirstKey+keyEpsilon*0.2, FirstPoint->Value));
            }
            lineData->append(QPointF(FirstKey+keyEpsilon*0.25, minValue));
            lineData->append(QPointF(FirstKey+keyEpsilon*0.75, maxValue));

            if (begIte->Key > FirstKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point
            {
                lineData->append(QPointF(FirstKey+keyEpsilon*0.8, (begIte-1)->Value));
            }
            lineData->append(QPointF(begIte->Key,begIte->Value));//添加最后一个点，不然数据空隙太大中间部分会消失
        } else{
            lineData->append(QPointF(FirstPoint->Key, FirstPoint->Value));
            lineData->append(QPointF(begIte->Key,begIte->Value));//添加最后一个点，不然数据空隙太大中间部分会消失
        }
    }
    else
    {
        while (begIte != endIte)
        {
            lineData->append(QPointF(begIte->Key,begIte->Value));
            ++begIte;
        }
        lineData->append(QPointF(begIte->Key,begIte->Value));
    }
}

void Plot::calculateTrackValue(QPoint Point)
{
    //计算跟踪值
    int index=0;
    double Key=0;
    for(int i=0;i<getGraphCount();i++)
    {
        Key=m_Tracking.m_PointCenter.x();
        PixelToCoorKey(Key,Graph(i)->getAixsType());

        QVector<_COORDINATEVALUE>::const_iterator begIte=Graph(i)->constBegIte();
        QVector<_COORDINATEVALUE>::const_iterator endIte=Graph(i)->constEndIte()-1;
        if(Key<begIte->Key||Key>endIte->Key){
           Graph(i)->setTrackIsvalid(false);
        }else{
            index=Graph(i)->getCoorToIndex(Key);
            Graph(i)->setTrackIsvalid(true);
            Graph(i)->setTrackValue(Graph(i)->getPoint(index));
        }
    }
    emit sig_UpdateTrack();
}

void Plot::paintEvent(QPaintEvent *event)
{
    QPainter painter;
    if(getTrackVisibel())
    {
        //点击跟踪点保存缓冲图像
        if(m_Tracking.m_First)
        {
            QPixmap pixmap=QPixmap(width(),height());
            m_PixMapCursor=pixmap;
            m_PixMapCursor.fill(m_BackgroundColor);//填充背景颜色，不然在arm平台有重影
            painter.begin(&m_PixMapCursor);
        }else{
            painter.begin(this);
        }
        if(m_Tracking.m_IsMove&&!m_Tracking.m_First){
            QPainter painter_2(this);
            QPixmap pixmapQ=m_PixMapCursor;
            painter_2.drawPixmap(rect(),pixmapQ);
        }else{
            drawGrid(&painter);
            drawPath(&painter);
            drawTickerX(&painter);
            drawTickerY_L(&painter);
            drawTickerY_R(&painter);
        }
        if(m_Tracking.m_First)
        {
            m_Tracking.m_First=false;
            QPainter painter_2(this);
            QPixmap pixmapQ=m_PixMapCursor;
            painter_2.drawPixmap(rect(),pixmapQ);
        }
        QPainter painter_3(this);
        drawCursor(&painter_3);
    }else{
        painter.begin(this);
        drawGrid(&painter);
        drawPath(&painter);
        drawTickerX(&painter);
        drawTickerY_L(&painter);
        drawTickerY_R(&painter);
    }
}

void Plot::drawGrid(QPainter *painter)
{
    painter->save();

    QPen Pen(QColor(85,85,85));
    Pen.setWidthF(1);
    painter->setPen(Pen);

    qreal Width=this->width();
    qreal Height=this->height();
    double VerSpace=Height/(m_TickerL->getMainLineCount());
    double LevSpace=Width/(m_TickerX->getMainLineCount());

    for(int i=0;i<(m_TickerX->getMainLineCount()-1);i++){
        painter->drawLine(LevSpace*(i+1),0,LevSpace*(i+1),Height);
    }

    for(int i=0;i<m_TickerL->getMainLineCount();i++){
        painter->drawLine(0,VerSpace*(i),Width,VerSpace*(i));
    }

//    //画最后一条线，单独画是为了防止计算精度问题导致隐藏该线
//    painter->drawLine(Width-1,0,Width-1,Height);
//    painter->drawLine(0,0,0,Height);
//    painter->drawLine(0,Height-1,Width,Height-1);

    painter->restore();
}

void Plot::drawPath(QPainter *painter)
{
    if(!m_IsDrawPath){
        return ;
    }
    painter->save();

    painter->translate(0,height());
    painter->scale(1, -1); //Y轴向上翻转，翻转成正常平面直角坐标系

    for(int index=0;index<getGraphCount();index++)
    {
        if(!Graph(index)->getVisible()){ continue; }
        QColor Line=this->Graph(index)->getColor();
        painter->setPen(Line);
        painter->setBrush(Qt::NoBrush);

        QVector<QPointF> lines;
        getOptimizedLineData(&lines,index);
        //qDebug()<<"lines"<<lines.first().rx()<<lines.last().rx();
//        qDebug()<<"lines"<<this->Graph(index)->Count()<<lines.count();
//        if(lines.count()==0){
//            qDebug()<<"lines"<<lines.count()<<endl;
//        }
        for(int i=0;i<lines.count();i++)
        {
            coordToPixel(lines[i].rx(),lines[i].ry(),this->Graph(index)->getAixsType());
            if(i==0){ continue; }
            painter->drawLine(lines.at(i-1),lines.at(i));
        }
    }
    painter->restore();
}

void Plot::drawCursor(QPainter *painter)
{
    painter->save();

    painter->setRenderHints(QPainter::Antialiasing);
    QRadialGradient radialGradient;
    radialGradient.setCenter(m_Tracking.m_PointCenter);
    radialGradient.setRadius(m_Tracking.m_radius);
    radialGradient.setFocalPoint(m_Tracking.m_PointCenter);
    if(m_Tracking.m_IsMove){
        radialGradient.setColorAt(0.0,QColor(161,140,209,180));
        radialGradient.setColorAt(1.0,QColor(251,194,235,180));
        painter->setPen(QColor(251,194,235));
    }else{
        radialGradient.setColorAt(0.0,QColor(134,143,150,150));
        radialGradient.setColorAt(1.0,QColor(59,97,100,150));
        painter->setPen(QColor(59,97,100));
    }
    painter->setBrush(radialGradient);
    int radius=m_Tracking.m_radius;
    if(m_Tracking.m_PointCenter.rx()<0){ m_Tracking.m_PointCenter.rx()=0; }
    if(m_Tracking.m_PointCenter.rx()>width()){ m_Tracking.m_PointCenter.rx()=width(); }
    if(m_Tracking.m_PointCenter.ry()<radius){ m_Tracking.m_PointCenter.ry()=radius; }
    if(m_Tracking.m_PointCenter.ry()>(height()-radius)){ m_Tracking.m_PointCenter.ry()=(height()-radius); }

    painter->save();
    painter->setPen(QColor(255,255,255));
    painter->drawLine(m_Tracking.m_PointCenter.x(),0,m_Tracking.m_PointCenter.x(),height());
    painter->drawLine(0,m_Tracking.m_PointCenter.y(),width(),m_Tracking.m_PointCenter.y());
    painter->restore();

    painter->drawEllipse(m_Tracking.m_PointCenter,radius,radius);
    painter->restore();

    calculateTrackValue(m_Tracking.m_PointCenter);
}

void Plot::drawTickerX(QPainter *painter)
{
    painter->save();
    QPen Pen(QColor(100,100,100));
    Pen.setWidthF(1);
    painter->setPen(Pen);

    Ticker *m_Ticker=m_TickerX;
    double Width=width();
    double Height=height();
    double MainSpace;
    double SubSpace;
    int MainLineCount=m_Ticker->getMainLineCount();
    int SubLineCount=m_Ticker->getSubLineCount();
    double MainOffset=0.0;
    double SubOffset=0.0;

    MainSpace=Width/MainLineCount;
    SubSpace=MainSpace/SubLineCount;
    //根据主刻度数目进行绘制
    for(int index=0;index<MainLineCount;index++)
    {
        MainOffset=MainSpace*index;
        if(index!=0)
        {
            painter->drawLine(MainOffset,Height,MainOffset,Height-m_Ticker->getMainLineLength());
        }

        for(int i=0;i<(SubLineCount-1);i++)
        {
            SubOffset=MainOffset+SubSpace*(i+1);
            painter->drawLine(SubOffset,Height,SubOffset,Height-m_Ticker->getSubLineLength());
        }
    }
    //绘制轴长线
    painter->drawLine(0,Height-1,Width,Height-1);

    painter->restore();
}

void Plot::drawTickerY_L(QPainter *painter)
{
    painter->save();
    QPen Pen(QColor(100,100,100));
    Pen.setWidthF(1);
    painter->setPen(Pen);

    Ticker *m_Ticker=m_TickerL;
    double Height=height();
    double MainSpace;
    double SubSpace;
    int MainLineCount=m_Ticker->getMainLineCount();
    int SubLineCount=m_Ticker->getSubLineCount();
    double MainOffset=0.0;
    double SubOffset=0.0;

    MainSpace=Height/MainLineCount;
    SubSpace=MainSpace/SubLineCount;

    //根据主刻度绘制
    for(int index=0;index<=MainLineCount;index++)
    {
        MainOffset=MainSpace*index;

        //绘制主刻度线
        if(index==MainLineCount){
            MainOffset=height()-1;
        }
        painter->drawLine(0,MainOffset,m_Ticker->getMainLineLength(),MainOffset);
        //绘制子刻度线
        if(index==MainLineCount){ continue; }
        for(int i=0;i<(SubLineCount-1);i++)
        {
            SubOffset=MainOffset+SubSpace*(i+1)+1;
            painter->drawLine(0,SubOffset,m_Ticker->getSubLineLength(),SubOffset);
        }
    }
    //绘制轴长线
    painter->drawLine(0,0,0,Height);
    painter->restore();
}

void Plot::drawTickerY_R(QPainter *painter)
{
    painter->save();
    QPen Pen(QColor(100,100,100));
    Pen.setWidthF(1);
    painter->setPen(Pen);

    Ticker *m_Ticker=m_TickerR;
    double Height=height();
    double Width=width();
    double MainSpace;
    double SubSpace;
    int MainLineCount=m_Ticker->getMainLineCount();
    int SubLineCount=m_Ticker->getSubLineCount();
    double MainOffset=0.0;
    double SubOffset=0.0;
    MainSpace=Height/MainLineCount;
    SubSpace=MainSpace/SubLineCount;
    for(int index=0;index<MainLineCount;index++)
    {

        MainOffset=MainSpace*index;
        if(index!=0)
        {
            painter->drawLine(Width-m_Ticker->getMainLineLength(),MainOffset,Width,MainOffset);
        }

        for(int i=0;i<(SubLineCount-1);i++)
        {
            SubOffset=MainOffset+SubSpace*(i+1);
            painter->drawLine(Width-m_Ticker->getSubLineLength(),SubOffset,Width,SubOffset);
        }
    }
    //绘制轴长线
    painter->drawLine(Width-1,0,Width-1,Height);
    painter->restore();
}

void Plot::wheelEvent(QWheelEvent *event)
{
    emit sig_sendCoorWheel(event);
    QWidget::wheelEvent(event);
}

void Plot::mousePressEvent(QMouseEvent *event)
{
    IsPress=true;
    QWidget::mousePressEvent(event);
    m_ClickedPoint=event->pos();
    emit sig_sendCoorMouse(event,m_ClickedPoint,true);

    //判断鼠标是否在焦点，在的话就移动
    bool TmpMoveCursor=m_Tracking.getIsRange(event->pos());
    if(m_Tracking.m_IsMove!=TmpMoveCursor)
    {
        m_Tracking.m_IsMove=TmpMoveCursor;
        m_Tracking.m_First=true;
        update();
    }
}

void Plot::mouseReleaseEvent(QMouseEvent *event)
{
    IsPress=false;
    if(m_Tracking.m_IsMove)
    {
        m_Tracking.m_IsMove=false;
        m_Tracking.m_First=false;
        update();
    }
    QWidget::mouseReleaseEvent(event);
}

void Plot::mouseMoveEvent(QMouseEvent *event)
{
    if(IsPress&&!m_IsTouch)
    {
        if(m_Tracking.m_IsMove)
        {
            m_Tracking.m_PointCenter=event->pos();
            emit update();
        }else{
            emit sig_sendCoorMouse(event,m_ClickedPoint,false);
        }
    }
}

void Plot::showEvent(QShowEvent *event)
{
    if(!m_Tracking.m_IsInit)
    {
        m_Tracking.m_IsInit=true;
        m_Tracking.m_PointCenter=QPoint(width()/2,height()/2);
    }
}

bool Plot::event(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::TouchBegin://第一次点击是触发
        break;
    case QEvent::TouchEnd://释放全部触点时触发
        m_IsTouch=false;
        break;
    case QEvent::TouchUpdate:
    {
        m_IsTouch=true;
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
        //总共返回的点数就是手指触摸的所有点数，先点击的点先加入列表，每个点的startPos()是点的时候的位置，pos()是移动后的当前位置
        QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
       // qDebug()<<"touchPoints"<<touchPoints.count()<<touchEvent->touchPointStates();
        if (touchPoints.count() == 2)//只处理两个点按下时的情况
        {
            const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
            const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();

            QLineF line1=QLineF(touchPoint0.startPos(), touchPoint1.startPos());
            QLineF line2=QLineF(touchPoint0.pos(), touchPoint1.pos());
            QPointF begCenter=line1.center();//起始中间点

            if(line1.dx()==0||line2.dx()==0||line1.dy()==0||line2.dy()==0){ return true;}

            qreal currentScaleFactorX =qAbs(line2.dx()/line1.dx());
            qreal currentScaleFactorY =qAbs(line2.dy()/line1.dy());

            m_scaleFactorX = currentScaleFactorX;
            m_scaleFactorY = currentScaleFactorY;

            if(touchEvent->touchPointStates().testFlag(Qt::TouchPointPressed))//点击的是获取重点坐标
            {
                //qDebug()<<"begCenter"<<begCenter<<m_scaleFactorX<<m_scaleFactorY;
                m_TickerX->InitScale();
                m_TickerL->InitScale();
                m_TickerR->InitScale();

                m_TickerX->getScale()._siteVal=begCenter.x();
                PixelToCoorKey(m_TickerX->getScale()._siteVal,_TICKERTYPE::XAxis);

                m_TickerL->getScale()._siteVal=height()-begCenter.y();//Y轴坐标翻转
                m_TickerR->getScale()._siteVal=height()-begCenter.y();//Y轴坐标翻转
                PixelToCoorValue(m_TickerL->getScale()._siteVal,_TICKERTYPE::YAxis_L);
                PixelToCoorValue(m_TickerR->getScale()._siteVal,_TICKERTYPE::YAxis_R);
            }
            //qDebug()<<"TouchPointPressed"<<m_scaleFactorX<<m_scaleFactorY<<line1.dx()<<line1.dy();

            //开始像素间隔大于100的时候才会缩放，不然可能会出现缩放小数太大的情况
            if(qAbs(line1.dx())>=100){
                m_TickerX->setScaleCoor(m_scaleFactorX);
            }
            if(qAbs(line1.dy())>=100){
                m_TickerL->setScaleCoor(m_scaleFactorY);
                m_TickerR->setScaleCoor(m_scaleFactorY);
            }
            emit sig_UpdateUI();
        }
    }
        break;
    default:
        break;
    }
    return QWidget::event(event);
}


//==============================================================================================

CurveWid::CurveWid(QWidget *parent) : QWidget(parent)
{
    QFont ft=this->font();
    ft.setPixelSize(14);
    this->setFont(ft);

    m_Plot=new Plot(this);

    m_AxisX=new CoorAxis(this,m_Plot->tickerX());
    m_AxisX->setMinimumHeight(10);
    m_AxisX->ticker()->setMainLineCount(5);
    m_AxisX->ticker()->setTextType(_TEXT_TYPE::CountVal);

    m_AxisL=new CoorAxis(this,m_Plot->tickerL());
    m_AxisL->ticker()->setMainLineCount(10);
    m_AxisL->setMinimumWidth(10);

    m_AxisR=new CoorAxis(this,m_Plot->tickerR());
    m_AxisR->ticker()->setMainLineCount(10);
    m_AxisR->setMinimumWidth(10);

    connect(m_Plot,&Plot::sig_sendCoorMouse,m_AxisX,&CoorAxis::slots_sendCoorMouse);
    connect(m_Plot,&Plot::sig_sendCoorWheel,m_AxisX,&CoorAxis::slots_sendCoorWheel);
    connect(m_Plot,&Plot::sig_sendCoorMouse,m_AxisL,&CoorAxis::slots_sendCoorMouse);
    connect(m_Plot,&Plot::sig_sendCoorWheel,m_AxisL,&CoorAxis::slots_sendCoorWheel);
    connect(m_Plot,&Plot::sig_sendCoorMouse,m_AxisR,&CoorAxis::slots_sendCoorMouse);
    connect(m_Plot,&Plot::sig_sendCoorWheel,m_AxisR,&CoorAxis::slots_sendCoorWheel);
    connect(m_Plot,&Plot::sig_UpdateUI,this,&CurveWid::slots_UpdateUI);

    connect(m_AxisX,&CoorAxis::sig_UpdateUI,this,&CurveWid::slots_UpdateUI);
    connect(m_AxisL,&CoorAxis::sig_UpdateUI,this,&CurveWid::slots_UpdateUI);
    connect(m_AxisR,&CoorAxis::sig_UpdateUI,this,&CurveWid::slots_UpdateUI);


    QSpacerItem *Item_H=new QSpacerItem(1,1,QSizePolicy::Expanding,QSizePolicy::Fixed);
    QSpacerItem *Item_V=new QSpacerItem(1,1,QSizePolicy::Fixed,QSizePolicy::Expanding);
    QGridLayout *G_layout=new QGridLayout;
    G_layout->setSpacing(0);
    G_layout->setContentsMargins(0,5,0,0);
    G_layout->addWidget(m_AxisL,0,0);
    G_layout->addWidget(m_Plot,0,1);
    G_layout->addWidget(m_AxisR,0,2);
    G_layout->addWidget(m_AxisX,1,1);
    G_layout->addItem(Item_H,2,1);
    G_layout->addItem(Item_V,0,3);
    this->setLayout(G_layout);

    m_Timer=new QTimer(this);
    connect(m_Timer,&QTimer::timeout,this,&CurveWid::slots_TimeOut);
}

void CurveWid::DataInit()
{

}

void CurveWid::reUpdate()
{
    m_Plot->update();
}

void CurveWid::reUpdateAll()
{
    m_AxisX->update();
    m_AxisL->update();
    m_AxisR->update();
    m_Plot->update();
//    static int count=0;
//    count++;
//    qDebug()<<"count"<<count;
}

void CurveWid::slots_UpdateUI()
{
    //reUpdateAll();
    if(!m_Timer->isActive()){
        m_Timer->start(10);
    }
}

void CurveWid::slots_TimeOut()
{
    reUpdateAll();
    m_Timer->stop();
}

void CurveWid::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    painter.setBrush(m_Plot->getBackgroundColor());//绘制背景颜色
    painter.drawRect(0,0,width(),height());
}
